home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
djgpp
/
samples
/
dpmi
/
pktdrvr.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-08-08
|
5KB
|
220 lines
#include <sys/types.h>
#include <stdio.h>
#include <go32.h>
#include <dos.h>
#include <dpmi.h>
#include <string.h>
#include <pc.h>
_go32_dpmi_seginfo dosmem;
int rmbuffer_full = 0;
int pd_test(int vector)
{
char sig[9];
unsigned short vec[2];
unsigned long pkt_addr;
dosmemget(vector*4, 4, vec);
pkt_addr = vec[1] * 16 + vec[0];
if (pkt_addr == 0)
return 0;
dosmemget(pkt_addr+3, 9, sig);
if (strcmp(sig, "PKT DRVR"))
return 0;
return 1;
}
void pd_get_etheraddr(int v, char *buf, int len)
{
_go32_dpmi_registers reg;
memset(®, 0, sizeof(reg));
reg.h.ah = 6;
reg.x.bx = 0;
reg.x.di = _go32_info_block.linear_address_of_transfer_buffer & 15;
reg.x.es = _go32_info_block.linear_address_of_transfer_buffer >> 4;
reg.x.cx = len;
_go32_dpmi_simulate_int(v, ®);
dosmemget(_go32_info_block.linear_address_of_transfer_buffer, len, buf);
}
void pd_send(int v, void *packet, int length)
{
_go32_dpmi_registers reg;
memset(®, 0, sizeof(reg));
reg.h.ah = 4;
reg.x.si = _go32_info_block.linear_address_of_transfer_buffer & 15;
reg.x.ds = _go32_info_block.linear_address_of_transfer_buffer >> 4;
reg.x.cx = length;
dosmemput(packet, length, _go32_info_block.linear_address_of_transfer_buffer);
_go32_dpmi_simulate_int(v, ®);
}
volatile int rmcb_happened = 0;
_go32_dpmi_registers rmcb_registers;
void rmcb(_go32_dpmi_registers *reg)
{
if (reg->x.ax == 0)
{
if (rmcb_happened)
reg->x.es = 0;
else
reg->x.es = dosmem.rm_segment;
reg->x.di = 0;
}
else
{
rmcb_happened = reg->x.cx;
}
}
int pd_read(char *buf)
{
int len = rmcb_happened;
while (!rmcb_happened && !kbhit());
if (kbhit())
{
getkey();
return 0;
}
dosmemget(dosmem.rm_segment*16, len, buf);
rmcb_happened = 0;
return len;
}
char test_arp[64] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0, 0, 0, 0, 0, 0,
0x08, 0x06,
0, 1, 8, 0, 6, 4, 0, 1,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0,
};
void pd_do(int v)
{
unsigned char ether[6];
int i;
_go32_dpmi_registers regs;
_go32_dpmi_seginfo rmcb_seginfo;
int handle;
printf("Packet driver detected at vector 0x%02x\n", v);
pd_get_etheraddr(v, ether, 6);
printf("This machine's ethernet address is %02x:%02x:%02x:%02x:%02x:%02x\n",
ether[0], ether[1], ether[2], ether[3], ether[4], ether[5]);
rmcb_seginfo.pm_offset = (int)rmcb;
if ((i=_go32_dpmi_allocate_real_mode_callback_retf(&rmcb_seginfo, &rmcb_registers)) != 0)
{
printf("Error: cannot allocate real mode callback, error=%04x\n", i);
return;
}
printf("real mode callback is at %04x:%04x\n", rmcb_seginfo.rm_segment, rmcb_seginfo.rm_offset);
memset(®s, 0, sizeof(regs));
regs.x.es = rmcb_seginfo.rm_segment;
regs.x.di = rmcb_seginfo.rm_offset;
regs.h.ah = 2;
regs.h.al = 1;
regs.x.bx = 0xffff;
regs.h.dl = 0;
regs.x.cx = 0;
_go32_dpmi_simulate_int(v, ®s);
if (regs.x.flags & 1)
{
printf("Error: packet driver receive accept refused\n");
return;
}
handle = regs.x.ax;
printf("packet driver acceptor allocated, handle = %d\n", handle);
memcpy(test_arp+6, ether, 6);
memcpy(test_arp+22, ether, 6);
pd_send(v, test_arp, 64);
printf("ARP packet sent, waiting. Press a key to abort.\n");
while (!kbhit() && !rmcb_happened);
if (kbhit())
{
printf("Keyboard interrupt\n");
getkey();
}
if (rmcb_happened)
{
unsigned char pkt[1600];
int len;
printf("Callback happened\n");
len = pd_read(pkt);
rmcb_happened = 0;
printf("Other machine's IP address is %02x:%02x:%02x:%02x:%02x:%02x\n",
pkt[22], pkt[23], pkt[24], pkt[25], pkt[26], pkt[27]);
}
memset(®s, 0, sizeof(regs));
regs.h.ah = 3;
regs.x.bx = handle;
_go32_dpmi_simulate_int(v, ®s);
printf("packet driver acceptor released\n");
_go32_dpmi_free_real_mode_callback(&rmcb_seginfo);
printf("real mode callback released\n");
}
void get_ip_address(char *msg, unsigned char *buffer)
{
int i[4], k;
while (1)
{
int invalid = 0;
i[3] = -1;
fputs(msg, stdout);
fflush(stdout);
scanf("%d.%d.%d.%d", i+0, i+1, i+2, i+3);
for (k=0; k<4; k++)
{
if (i[k] < 0 || i[k] > 255)
invalid = 1;
else
buffer[k] = i[k];
}
if (!invalid)
return;
printf("Invalid IP address. Expected something like 128.0.0.7\n");
}
}
int main()
{
int v;
printf("Packet Driver test - arp\n");
get_ip_address("Enter this machine's IP address : ", test_arp+28);
get_ip_address("Enter other machine's IP address : ", test_arp+38);
printf("go32 segments: cs=%04x ds=%04x ss=%04x\n", _go32_my_cs(), _go32_my_ds(), _go32_my_ss());
dosmem.size = 100;
if (_go32_dpmi_allocate_dos_memory(&dosmem))
{
printf("Unable to allocate dos memory - max size is %d\n", dosmem.size);
exit(1);
}
printf("dos buffer at 0x%04x:0\n", dosmem.rm_segment);
for (v=0x60; v<0x80; v++)
{
if (pd_test(v))
pd_do(v);
}
_go32_dpmi_free_dos_memory(&dosmem);
printf("dos buffer released\n");
return 0;
}